package com.zzyl.framework.interceptor;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.zzyl.common.core.domain.model.LoginUser;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.SecurityUtils;
import com.zzyl.common.utils.UserThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

/**
 * @author zzw
 */
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {

    // 保留默认用户ID
    private static final Long DEFAULT_USER_ID = 1L;

    // 明确区分线程类型
    private static final String[] ASYNC_THREAD_PREFIXES = {
            "quartzScheduler_Worker",
            "threadPoolTaskExecutor"
    };

    @Autowired
    private HttpServletRequest request;

    /**
     * 是否应该填充用户信息 (修正后的逻辑)
     */
    private boolean isExclude() {
        // 1. 异步线程不填充
        String threadName = Thread.currentThread().getName();
        if (Arrays.stream(ASYNC_THREAD_PREFIXES).anyMatch(threadName::startsWith)) {
            return false;
        }

        // 2. 有请求上下文时才填充
        try {
            // 只要不是异步线程且有请求就填充
            return request != null;
        }
        catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断是否小程序请求
     */
    private boolean isMemberRequest() {
        try {
            return request.getRequestURI().startsWith("/member");
        }
        catch (Exception e) {
            return false;
        }
    }


    @Override
    public void insertFill(MetaObject metaObject) {
        // 统一处理创建信息
        fillCreateInfo(metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 统一处理更新信息
        fillUpdateInfo(metaObject);
    }

    /**
     * 填充创建信息
     */
    private void fillCreateInfo(MetaObject metaObject) {
        Date now = DateUtils.getNowDate();

        // 1. 处理创建人
        if (isExclude()) {
            Long userId = isMemberRequest() ?
                    getWxLoginUserId() : getLoginUserId();
            this.strictInsertFill(metaObject, "createBy", String.class, String.valueOf(userId));
        }

        // 2. 处理创建时间
        this.strictInsertFill(metaObject, "createTime", Date.class, now);
    }

    /**
     * 填充更新信息
     */
    private void fillUpdateInfo(MetaObject metaObject) {
        Date now = DateUtils.getNowDate();

        // 1. 处理更新人
        if (isExclude()) {
            Long userId = isMemberRequest() ?
                    getWxLoginUserId() : getLoginUserId();
            this.setFieldValByName("updateBy", String.valueOf(userId), metaObject);
        }

        // 2. 处理更新时间
        this.setFieldValByName("updateTime", now, metaObject);
    }

    /**
     * 获取系统登录用户ID
     */
    public Long getLoginUserId() {
        try {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            return ObjectUtils.isNotEmpty(loginUser) ?
                    loginUser.getUserId() : DEFAULT_USER_ID;
        }
        catch (Exception e) {
            log.error("获取系统登录用户ID失败", e);
            return DEFAULT_USER_ID;
        }
    }

    /**
     * 获取微信登录用户ID
     */
    public Long getWxLoginUserId() {
        try {
            Long userId = UserThreadLocal.getUserId();
            return ObjectUtils.isNotEmpty(userId) ?
                    userId : DEFAULT_USER_ID;
        }
        catch (Exception e) {
            log.error("获取微信登录用户ID失败", e);
            return DEFAULT_USER_ID;
        }
    }
}
